#include "TcpServer.hpp"
#include "Http.hpp"
#include "session.hpp"

void Usage(std::string proc)
{
  std::cout << "Usage:\n\t" << proc << " local_port\n"
            << std::endl;
}

std::string GetMonthName(int month)
{
  std::vector<std::string> months = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
  return months[month];
}
std::string GetWeekDayName(int day)
{
  std::vector<std::string> weekdays = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
  return weekdays[day];
}
std::string ExpireTimeUseRfc1123(int t) // 秒级别的未来UTC时间
{
  time_t timeout = time(nullptr) + t;
  struct tm *tm = gmtime(&timeout); // 这里不能用localtime，因为localtime是默认带了时区的. gmtime获取的就是UTC统一时间
  char timebuffer[1024];
  // 时间格式如: expires=Thu, 18 Dec 2024 12:00:00 UTC
  snprintf(timebuffer, sizeof(timebuffer), "%s, %02d %s %d %02d:%02d:%02d UTC",
           GetWeekDayName(tm->tm_wday).c_str(),
           tm->tm_mday,
           GetMonthName(tm->tm_mon).c_str(),
           tm->tm_year + 1900,
           tm->tm_hour,
           tm->tm_min,
           tm->tm_sec);
  return timebuffer;
}

std::shared_ptr<HttpResponse> Login(std::shared_ptr<HttpRequest> req)
{
  LOG(DEBUG, "=========================");
  std::string userdata;
  if (req->Method() == "GET")
  {
    userdata = req->Args();
  }
  else if (req->Method() == "POST")
  {
    userdata = req->Text();
  }
  else
  {
  }

  // 1. 进程间通信， 比如 pipe！ 还有环境变量！

  // 2. fork();

  // 3. exec(); python / php / java / C++

  // 处理数据了
  LOG(DEBUG, "enter data handler, data is : %s", userdata.c_str());

  auto response = Factory::BuildHttpResponose();
  response->AddStatusLine(200, "OK");
  response->AddHeader("Content-Type", "text/html");
  response->AddHeader("Set-Cookie", "username=zhangsan; path=/a/b; expires=" + ExpireTimeUseRfc1123(60) + ";"); // 让cookie 1min后过期
  response->AddText("<html><h1>handler data done</h1></html>");
  LOG(DEBUG, "=========================");
  return response;
}

// ./tcpserver port
// 云服务器的port默认都是禁止访问的。云服务器放开端口8080 ~ 8085
int main(int argc, char *argv[])
{
  if (argc != 2)
  {
    Usage(argv[0]);
    // exit(USAGE_ERROR);
    return 1;
  }
  uint16_t port = std::stoi(argv[1]);
  HttpServer httpservice;

  // 仿照路径，来进行功能路由！
  httpservice.AddHandler("/login", Login);
  // httpservice.AddHandler("/register", Login);
  // httpservice.AddHandler("/s", Search);
  TcpServer tcpsvr(port, std::bind(&HttpServer::HandlerHttpRequest, &httpservice, std::placeholders::_1));
  tcpsvr.Loop();
  return 0;
}